macos: implement compute_size and request_layout
authorChristian Hergert <chergert@redhat.com>
Fri, 1 Jan 2021 21:11:29 +0000 (13:11 -0800)
committerChristian Hergert <chergert@redhat.com>
Fri, 1 Jan 2021 21:17:47 +0000 (13:17 -0800)
These functions were not implemented when the sizing changes
landed before GTK 4 was released. This fixes an issue with non-
resizeable windows not reacting to layout changes.

Fixes #3532

gdk/macos/gdkmacossurface-private.h
gdk/macos/gdkmacostoplevelsurface.c

index 6c04b070661271e64741731edcecfc459887e499..c366c0b4e6fb72697266dbc50f3bc1cc5c80d865 100644 (file)
@@ -61,6 +61,7 @@ struct _GdkMacosSurface
   gint64 pending_frame_counter;
 
   guint did_initial_present : 1;
+  guint geometry_dirty : 1;
 };
 
 struct _GdkMacosSurfaceClass
index 54c991bdf2ba82a805fa0895501d0f1dc390c7c4..5bce4101dfaad74be23904bd28b0dbef158b7d6a 100644 (file)
@@ -107,6 +107,7 @@ _gdk_macos_toplevel_surface_present (GdkToplevel       *toplevel,
   style_mask = [nswindow styleMask];
 
   monitor = gdk_display_get_monitor_at_surface (display, surface);
+
   if (monitor)
     {
       GdkRectangle workarea;
@@ -158,13 +159,11 @@ _gdk_macos_toplevel_surface_present (GdkToplevel       *toplevel,
     [nswindow setStyleMask:style_mask];
 
   if (size.shadow.is_valid)
-    {
-      _gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
-                                     size.shadow.top,
-                                     size.shadow.right,
-                                     size.shadow.bottom,
-                                     size.shadow.left);
-    }
+    _gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
+                                   size.shadow.top,
+                                   size.shadow.right,
+                                   size.shadow.bottom,
+                                   size.shadow.left);
 
   _gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
   gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
@@ -371,6 +370,87 @@ _gdk_macos_toplevel_surface_hide (GdkSurface *surface)
   GDK_SURFACE_CLASS (_gdk_macos_toplevel_surface_parent_class)->hide (surface);
 }
 
+static gboolean
+_gdk_macos_toplevel_surface_compute_size (GdkSurface *surface)
+{
+  GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)surface;
+  NSWindow *nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
+  GdkToplevelSize size;
+  GdkDisplay *display;
+  GdkMonitor *monitor;
+  int bounds_width, bounds_height;
+  int width, height;
+  GdkGeometry geometry;
+  GdkSurfaceHints mask;
+  NSWindowStyleMask style_mask;
+
+  g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
+
+  if (!GDK_MACOS_SURFACE (surface)->geometry_dirty)
+    return FALSE;
+
+  GDK_MACOS_SURFACE (surface)->geometry_dirty = FALSE;
+
+  display = gdk_surface_get_display (surface);
+  monitor = gdk_display_get_monitor_at_surface (display, surface);
+  style_mask = [nswindow styleMask];
+
+  if (monitor)
+    {
+      GdkRectangle workarea;
+
+      gdk_macos_monitor_get_workarea (monitor, &workarea);
+      bounds_width = workarea.width;
+      bounds_height = workarea.height;
+    }
+  else
+    {
+      bounds_width = G_MAXINT;
+      bounds_height = G_MAXINT;
+    }
+
+  gdk_toplevel_size_init (&size, bounds_width, bounds_height);
+  gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
+
+  g_warn_if_fail (size.width > 0);
+  g_warn_if_fail (size.height > 0);
+
+  width = size.width;
+  height = size.height;
+
+  if (style_mask & NSWindowStyleMaskResizable)
+    {
+      geometry.min_width = size.min_width;
+      geometry.min_height = size.min_height;
+      mask = GDK_HINT_MIN_SIZE;
+    }
+  else
+    {
+      geometry.max_width = geometry.min_width = width;
+      geometry.max_height = geometry.min_height = height;
+      mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
+    }
+
+  if (size.shadow.is_valid)
+    _gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
+                                   size.shadow.top,
+                                   size.shadow.right,
+                                   size.shadow.bottom,
+                                   size.shadow.left);
+
+  _gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
+  gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
+  _gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);
+
+  return FALSE;
+}
+
+static void
+_gdk_macos_toplevel_surface_request_layout (GdkSurface *surface)
+{
+  GDK_MACOS_SURFACE (surface)->geometry_dirty = TRUE;
+}
+
 static void
 _gdk_macos_toplevel_surface_destroy (GdkSurface *surface,
                                      gboolean    foreign_destroy)
@@ -504,6 +584,8 @@ _gdk_macos_toplevel_surface_class_init (GdkMacosToplevelSurfaceClass *klass)
 
   surface_class->destroy = _gdk_macos_toplevel_surface_destroy;
   surface_class->hide = _gdk_macos_toplevel_surface_hide;
+  surface_class->compute_size = _gdk_macos_toplevel_surface_compute_size;
+  surface_class->request_layout = _gdk_macos_toplevel_surface_request_layout;
 
   gdk_toplevel_install_properties (object_class, LAST_PROP);
 }